<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/limh/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/limh/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/limh/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/limh/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/limh/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/limh/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/limh/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="教程,">










<meta name="description" content="计算机系统有上百种中断，若按中断的性质来划分，则系统中的中断可分为：可屏蔽中断和不可屏蔽中断。对不可屏蔽中断，程序员不能控制它，系统肯定会立即响应的，而对于可屏蔽中断，汇编语言程序员可以通过指令CLI和STI来控制对它们的响应。 若按中断源来划分，则系统中的中断又可分为：硬件中断和软件中断。对于硬件中断，程序员不能控制它，它们基本上是随机产生的，而对于软件中断，汇编语言程序员可通过指令INT和IN">
<meta name="keywords" content="教程">
<meta property="og:type" content="article">
<meta property="og:title" content="8.3 中断功能的分类">
<meta property="og:url" content="https://tdnr.gitee.io/limh/2015/04/01/asm36/index.html">
<meta property="og:site_name" content="土逗牛肉">
<meta property="og:description" content="计算机系统有上百种中断，若按中断的性质来划分，则系统中的中断可分为：可屏蔽中断和不可屏蔽中断。对不可屏蔽中断，程序员不能控制它，系统肯定会立即响应的，而对于可屏蔽中断，汇编语言程序员可以通过指令CLI和STI来控制对它们的响应。 若按中断源来划分，则系统中的中断又可分为：硬件中断和软件中断。对于硬件中断，程序员不能控制它，它们基本上是随机产生的，而对于软件中断，汇编语言程序员可通过指令INT和IN">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0105.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image002_0041.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0106.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image002_0042.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image003_0026.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image004_0016.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image006_0009.gif">
<meta property="og:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0107.gif">
<meta property="og:updated_time" content="2019-01-22T06:54:40.143Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="8.3 中断功能的分类">
<meta name="twitter:description" content="计算机系统有上百种中断，若按中断的性质来划分，则系统中的中断可分为：可屏蔽中断和不可屏蔽中断。对不可屏蔽中断，程序员不能控制它，系统肯定会立即响应的，而对于可屏蔽中断，汇编语言程序员可以通过指令CLI和STI来控制对它们的响应。 若按中断源来划分，则系统中的中断又可分为：硬件中断和软件中断。对于硬件中断，程序员不能控制它，它们基本上是随机产生的，而对于软件中断，汇编语言程序员可通过指令INT和IN">
<meta name="twitter:image" content="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0105.gif">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/limh/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://tdnr.gitee.io/limh/2015/04/01/asm36/">





  <title>8.3 中断功能的分类 | 土逗牛肉</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans ">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/limh/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">土逗牛肉</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/limh/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br>
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/limh/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/limh/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/limh/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br>
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/limh/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br>
            
            关于
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://tdnr.gitee.io/limh/limh/2015/04/01/asm36/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="土逗牛肉">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/limh/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="土逗牛肉">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">8.3 中断功能的分类</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2015-04-01T20:36:01+08:00">
                2015-04-01
              </time>
            

            

            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/limh/categories/汇编教程/" itemprop="url" rel="index">
                    <span itemprop="name">汇编教程</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>计算机系统有上百种中断，若按中断的性质来划分，则系统中的中断可分为：可屏蔽中断和不可屏蔽中断。对不可屏蔽中断，程序员不能控制它，系统肯定会立即响应的，而对于可屏蔽中断，汇编语言程序员可以通过指令CLI和STI来控制对它们的响应。</p>
<p>若按中断源来划分，则系统中的中断又可分为：硬件中断和软件中断。对于硬件中断，程序员不能控制它，它们基本上是随机产生的，而对于软件中断，汇编语言程序员可通过指令INT和INTO来有目的安排它们的。</p>
<p>下面主要介绍汇编语言程序员能控制的软件中断的功能及其使用方法，常用的这类中断有：DOS功能调用(INT 21H)、BIOS中断、硬件和外设的中断等。</p>
<p>图8.4给出了程序员可使用的各类中断之间的层次关系。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0105.gif" alt></p>
<center><strong>图8.4 各类系统中断之间的层次关系</strong></center>

<p>在用户程序中，若直接通过端口来操作硬件或外设，那么，其处理过程没有额外的多余工作，处理速度显然是最快的，但这样做，无疑使用户程序具有了很大的局限性。硬件环境的改变将直接影响程序的正常运行。</p>
<p>若用户程序通过调用DOS功能来实现其所需功能，那么，应用程序与低层硬件相距较远，操作最终的对象需要经过中间环节，处理速度肯定受到一定的损失，但这种应用程序适应性强，应用范围广，对硬件的依赖性最小。</p>
<p>由于BIOS介于DOS和具体硬件之间，所以，调用BIOS的功能是一个很好的折中方案。程序员可在以下三种情况下考虑使用BIOS的功能：</p>
<ol>
<li>BIOS提供的功能，而DOS没有提供该功能的情况；</li>
<li>不能利用DOS功能调用的情况(可能因为某些具体应用的限制)；</li>
<li>基于处理速度的考虑，需要绕过DOS层的情况。</li>
</ol>
<p>综上所述，可以归纳出如下结论：使用中断的层次越高，它与硬件设备相关程度就越低，处理速度也就越低，但用户程序的适用范围较广。反之也然。</p>
<p>有了上面的结论，程序员可根据应用程序的要求、对硬件环境的熟悉程度等因素来选用不同层次的中断。</p>
<h2 id="8-3-1-键盘输入的中断功能"><a href="#8-3-1-键盘输入的中断功能" class="headerlink" title="8.3.1 键盘输入的中断功能"></a>8.3.1 键盘输入的中断功能</h2><p>键盘输入是绝大多数程序的主要输入方式，学习和掌握有关键盘输入中断的使用方法对编写交互式程序是非常重要的，也能更进一步理解计算机是如何接受键盘输入的。</p>
<h3 id="1、键盘缓冲区"><a href="#1、键盘缓冲区" class="headerlink" title="1、键盘缓冲区"></a>1、键盘缓冲区</h3><p>键盘缓冲区是一个先进先出的环形队列，其所占内存区域如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">KBHead DW　 ;其内存地址为0000:041AH，缓冲区头指针</span><br><span class="line"></span><br><span class="line">KBTail DW　 ;其内存地址为0000:041CH，缓冲区尾指针</span><br><span class="line"></span><br><span class="line">KBBuff? DW　16 DUP(?)? ;其内存地址为0000:041EH，该缓冲区的缺省长度为16个字</span><br></pre></td></tr></table></figure>
<p>与键盘有关的其它地址请见附录6之键盘地址。</p>
<p>键盘缓冲区是一个环形队列，其性质与《数据结构》课程中对“环形队列”所描述的性质完全一致。虽然缓冲区的本身长度为16个字，但出于判断“对列满”的考虑，它最多只能保存15个键盘信息。当缓冲区满时，系统将不再接受按键信息，而会发出“嘟”的声音，以示要暂缓按键。当KBHead＝KBTail时，表示无键盘输入。</p>
<h3 id="2、键盘状态字"><a href="#2、键盘状态字" class="headerlink" title="2、键盘状态字"></a>2、键盘状态字</h3><p>在计算机键盘上除了可输入各种字符(字母、数字和符号等)的按键之外，还有一些功能键(如：F1、F2、…等)、控制键(如：Ctrl、Alt、Shift等)、双态键(如：Num Lock、Caps Lock等)和特殊请求键(如：Print Screen、Scroll Lock等)。</p>
<p>键盘中的控制键和双态键是非打印按键，它们是起控制或转换作用的。当使用者按下控制键或双态键时，系统要记住其所按下的按键。为此，在计算机系统中，特意安排的一个字来标志这些按键的状态，我们称该字为键盘状态字。</p>
<p>键盘状态字的各位含义如图8.5所示。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image002_0041.gif" alt></p>
<center><strong>图8.5 键盘状态字的各位含义</strong></center>

<h3 id="3、键盘中断的处理过程"><a href="#3、键盘中断的处理过程" class="headerlink" title="3、键盘中断的处理过程"></a>3、键盘中断的处理过程</h3><p>当用户按键时，键盘接口会得到一个代表该按键的键盘扫描码，同时产生一个中断请求。键盘中断服务程序先从键盘接口取得按键的扫描码，然后根据其扫描码判断用户所按的键并作相应的处理，最后通知中断控制器本次中断结束并实现中断返回。</p>
<ol>
<li>若用户按下双态键(如：Caps Lock、Num Lock和Scroll Lock等)，则在键盘上相应LED指示灯的状态将发生改变；</li>
<li>若用户按下控制键(如：Ctrl、Alt和Shift等)，则在键盘标志字中设置其标志位；</li>
<li>若用户按下功能键(如：F1、F2、…等)，再根据当前是否又按下控制键来确定其系统扫描码，并把其系统扫描码和一个值为0的字节存入键盘缓冲区；</li>
<li>若用户按下字符键(如：A、1、+、…等)，此时，再根据当前是否又按下控制键来确定其系统扫描码，并得到该按键所对应的ASCII码，然后把其系统扫描码和ASCII码一起存入键盘缓冲区；</li>
<li>若用户按下功能请求键(如：Print Screen等)，则系统直接产生一个具体的动作。</li>
</ol>
<p>有关键盘中各种单键、组合键的扫描码及其相应的ASCII码，请参阅本书的附录5。</p>
<h3 id="4、DOS功能中的键盘输入"><a href="#4、DOS功能中的键盘输入" class="headerlink" title="4、DOS功能中的键盘输入"></a>4、DOS功能中的键盘输入</h3><p>键盘输入是一种最常用的输入方式，所以，在DOS操作系统中，提供了能实现各种键盘输入的功能(Windows操作系统中仍然能用)。INT 21H中的相关功能如下：</p>
<ul>
<li>01H——带回显的键盘输入</li>
<li>06H——控制台的输入/输出：当DL=0FFH，表示键盘输入</li>
<li>07H——不回显、不过滤的键盘输入</li>
<li>08H——不回显的键盘输入</li>
<li>0AH——键盘输入字符串</li>
<li>0BH——检查键盘输入状态</li>
<li>0CH——清除输入缓冲区的输入功能</li>
</ul>
<p>有关中断功能的详细描述和调用参数在此从略，需要查阅者可参阅附录3之字符功能调用类。</p>
<h3 id="5、BIOS中的键盘输入"><a href="#5、BIOS中的键盘输入" class="headerlink" title="5、BIOS中的键盘输入"></a>5、BIOS中的键盘输入</h3><p>在BIOS系统中，提供了中断16H来实现键盘输入功能。其具体的功能如下：</p>
<p>00H、10H——从键盘读一个字符，输入字符不回显</p>
<p>01H、11H——判断键盘缓冲区内是否有字符可读</p>
<p>02H——读取当前键盘状态字</p>
<p>有关中断功能的详细描述和调用参数在此从略，需要查阅者可参阅附录3之键盘服务。</p>
<h3 id="6、直接操作端口的键盘输入"><a href="#6、直接操作端口的键盘输入" class="headerlink" title="6、直接操作端口的键盘输入"></a>6、直接操作端口的键盘输入</h3><p>由表8.1可知：键盘输入端口的地址为60H，所以，我们可以用指令IN从该端口读取当前按键的扫描码。</p>
<p>例如：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">MOV　DX, 60H </span><br><span class="line"> IN　　 AL, DX</span><br></pre></td></tr></table></figure>
<h3 id="7、键盘输入的举例"><a href="#7、键盘输入的举例" class="headerlink" title="7、键盘输入的举例"></a>7、键盘输入的举例</h3><p><strong>例8.1 用键盘最多输入10个字符，并存入内存变量Buff中，若按“Enter”键，则表示输入结束。</strong></p>
<p>解：</p>
<p><strong>1、方法1</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">.MODEL SMALL</span><br><span class="line"></span><br><span class="line">CR　EQU　0DH ;定义“回车”键的符号名 </span><br><span class="line"></span><br><span class="line">.DATA</span><br><span class="line"></span><br><span class="line">Buff　DB　10 DUP(?)</span><br><span class="line"></span><br><span class="line">.CODE</span><br><span class="line"></span><br><span class="line">.STARTUP</span><br><span class="line"></span><br><span class="line">MOV　CX, 0AH</span><br><span class="line"></span><br><span class="line">LEA　BX, Buff</span><br><span class="line"></span><br><span class="line">.REPEAT</span><br><span class="line"></span><br><span class="line">MOV　AH, 0H</span><br><span class="line"></span><br><span class="line">INT　16H? ;用BIOS中的中断功能 </span><br><span class="line"></span><br><span class="line">.BREAK　.IF　AL==CR</span><br><span class="line"></span><br><span class="line">MOV　[BX], AL</span><br><span class="line"></span><br><span class="line">INC　BX</span><br><span class="line"></span><br><span class="line">.UNTILCXZ</span><br><span class="line"></span><br><span class="line">.EXIT?0</span><br><span class="line"></span><br><span class="line">END</span><br></pre></td></tr></table></figure>
<p><strong>2、方法2</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">.MODEL　SMALL</span><br><span class="line"></span><br><span class="line">.DATA</span><br><span class="line"></span><br><span class="line">Buff　DB　10, ?, 10 DUP(?) ;注意缓冲区的定义方式 </span><br><span class="line"></span><br><span class="line">.CODE</span><br><span class="line"></span><br><span class="line">.STARTUP</span><br><span class="line"></span><br><span class="line">LEA　DX, Buff</span><br><span class="line"></span><br><span class="line">MOV　AH, 0AH</span><br><span class="line"></span><br><span class="line">INT　21H ;用DOS中的功能调用 </span><br><span class="line"></span><br><span class="line">.EXIT　0</span><br><span class="line"></span><br><span class="line">END</span><br></pre></td></tr></table></figure>
<h2 id="8-3-2-屏幕显示的中断功能"><a href="#8-3-2-屏幕显示的中断功能" class="headerlink" title="8.3.2 屏幕显示的中断功能"></a>8.3.2 屏幕显示的中断功能</h2><p>显示器是一个重要的输出设备，它通过显示卡与计算机系统相连。显示器的显示屏通常称之为屏幕，现在常用的显示器有14”和17”，常用的显示分辨率为800×600或1024×768等。常用的显示卡类型为VGA、SVGA、EVGA和TVGA等，显示卡上也都带有大量的显示存储器，能快速显示精美的图象。</p>
<h3 id="1、显示模式"><a href="#1、显示模式" class="headerlink" title="1、显示模式"></a>1、显示模式</h3><p>计算机系统中的显示器都有二种显示方式：文本显示方式和图形显示方式。在DOS操作系统环境下，其默认的显示方式为文本显示方式，而在Windows操作系统环境下，其显示方式是图形显示方式，其绝大多数操作界面是以图形界面的窗口形式出现的。</p>
<p>可用的显示模式，请参阅附录3中的中断10H之功能00H中所列。</p>
<h4 id="1-、文本显示方式"><a href="#1-、文本显示方式" class="headerlink" title="1)、文本显示方式"></a>1)、文本显示方式</h4><p>文本显示方式是指以字符为最小单位的显示方式，每个字符都是以矩形块形式显示的。在BIOS ROM中存有多种不同大小的字符集，主要的显示字符集大小为：8×8(标准)、8×14和8×16等。</p>
<p>在常用的文本显示模式(模式3)下，屏幕被划分成25行，每行可显示80个字符，所以，每屏最多可显示2000(80×25)个字符。为了便于标识屏幕上的每个显示位置，我们就用其所在行和列来表示之，并规定：屏幕的左上角坐标为(0, 0)，右下角坐标为(24, 79)。</p>
<p>在显示字符时，用一个字节存储该字符的ASCII码，用另一个字节存储的显示属性，即：显示颜色。彩色显示器的字符显示属性定义如图8.6所示，有关颜色值的定义，请参阅附录6中的表4。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0106.gif" alt></p>
<center><strong>图8.6 字符显示属性的定义</strong></center>

<p>存储内容与显示位置的对应关系如图8.7所示。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image002_0042.gif" alt></p>
<center><strong>图8.7 存储内容与显示位置的对应关系示意图</strong></center>

<p>由上面的叙述可知：在80×25的文本显示模式下，满屏可显示2000个字符，也就需要4000个字节来存储一屏的显示信息。</p>
<h4 id="2-、图形显示方式"><a href="#2-、图形显示方式" class="headerlink" title="2)、图形显示方式"></a>2)、图形显示方式</h4><p>图形显示是目前最常用的一种显示方式，也是Windows操作系统的默认显示方式。在该显示方式下，我们可以看到优美的图象、VCD、浏览丰富多彩的网页等。</p>
<p>图形显示的最小单位是象素，对每个象素可用不同的颜色来显示。所以，在显示缓冲区内记录的信息是屏幕各象素的显示颜色。</p>
<p>由于各种图形显示模式所能显示的颜色和象素是不同的，它决定了显示缓冲区的存储方式也是不同的。下面给出三个具体的图形显示模式及其存储方式，通过它们可看出各种显示模式在显示缓冲区存储方式上的明显差异。</p>
<h5 id="1-、4色320×200图形显示模式"><a href="#1-、4色320×200图形显示模式" class="headerlink" title="(1)、4色320×200图形显示模式"></a>(1)、4色320×200图形显示模式</h5><p>由于每个象素只能是四种颜色之一，而四种情况用2位二进制就可表示，所以，一个字节可表示4个象素的显示颜色，存储一行上的所有象素信息就需要80个字节。</p>
<p>在具体存储过程中，它又把偶数行象素和齐数行分开来存储。偶数行和齐数行的象素总数各有32000个，也都需要8000个字节来存储，并规定：偶数行象素从0B800:0000H开始存储，齐数行象素从0B800:2000H开始存储。该显示模式的存储形式如图8.8所示。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image003_0026.gif" alt="图8.8 显示缓冲区存储方式示意图"></p>
<center><strong>图8.8 显示缓冲区存储方式示意图</strong></center>

<h5 id="2-、16色640×480图形显示模式"><a href="#2-、16色640×480图形显示模式" class="headerlink" title="(2)、16色640×480图形显示模式"></a>(2)、16色640×480图形显示模式</h5><p>640×480图形显示模式共有307200个象素，每个象素可选用16种颜色，它需要用4位二进制来表示。该显示模式在存储显示信息时，把该4位分在四个位平面P1、P2、P3和P4上，所以，位平面Pi(i=1,2,3,4)共有307200个二进制位，即有38400个字节。其显示缓冲区的存储形式如图8.9所示。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image004_0016.gif" alt></p>
<center><strong>图8.9 显示缓冲区存储方式示意图</strong></center>

<p>由图8.9可看出：若要改变某个象素的显示颜色，则需要在每个位平面上修改其对应的二进制位。所以，若用操作显示缓冲区的方法来改变象素的颜色，那么编程将困难得多。在屏幕上显示一个点，必须遵循以下步骤：</p>
<ul>
<li>读入要改变的内存单元，把位平面信息装入显示卡；</li>
<li>通过图形地址寄存器(GAR)和位屏蔽寄存器(BMR)选择并寻址到其二进制位；</li>
<li>寻址并设定映像屏蔽寄存器(MMR)为0FH，在对应象素地址填入0(黑色)来清除象素的原有颜色；</li>
<li>通过MMR设定该象素当前所要颜色；</li>
<li>通过修改包含显示信息的内存单元来写象素。</li>
</ul>
<p>对于该显示模式下，改变象素方法的详细描述和例子，请参阅参考书籍[2]、[4]，或其它有关技术资料，在此不再进一步展开叙述。</p>
<p>若用BIOS中断10H之功能0DH/0CH来读/写象素，则它可屏蔽掉各种显示模式的差异，用同样的参数完成同样的功能。所以，在此建议：使用系统中断的方法来实现对图形象素的操作。</p>
<h5 id="3-、256色320×200图形显示模式"><a href="#3-、256色320×200图形显示模式" class="headerlink" title="(3)、256色320×200图形显示模式"></a>(3)、256色320×200图形显示模式</h5><p>表达256种不同颜色需要8位二进制，即一个字节。在该模式下，其显示缓冲区的存储方式是非常简单的，即：第一个字节存储第一个象素的颜色，第二个字节存储第二个象素的颜色，以此类推，所以，存储满屏象素所需要的字节数为：320×200×1＝64000。其显示缓冲区的存储方式如图8.10所示。</p>
<p>从上面三种不同图形显示模式的介绍，不难看出：各种显示模式在显示缓冲区存储方式上的明显差异，操作象素方法的难易程度相差也很大，所以，再次建议：程序员不要用直接操作显示缓冲区的办法来达到改变显示象素的目的，最好是通过BIOS内的中断功能来实现相应的功能，这样，所编写的程序能很方便地适应不同的图形显示模式。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image006_0009.gif" alt></p>
<center><strong>图8.10 显示缓冲区存储方式示意图</strong></center>

<h3 id="2、显示缓冲区"><a href="#2、显示缓冲区" class="headerlink" title="2、显示缓冲区"></a>2、显示缓冲区</h3><p>显示缓冲区是用来记录屏幕显示信息的。在文本显示方式下，这些显示信息包括：每个显示字符的ASCII码及其显示属性，如图8.7所示。在图形显示方式下，显示缓冲区内存储每个象素的显示颜色。</p>
<p>在图8.7中，我们并没有给出具体的段地址，只用”XXXX”来表示其段地址。在常用的VGA显示方式下，计算机系统规定：</p>
<ul>
<li>文本显示方式下，单色显示器的显示缓冲区段地址为0B000H；</li>
<li>文本显示方式下，彩色显示器显示缓冲区段地址为0B800H；</li>
<li>图形显示方式下，其显示缓冲区段地址为0A000H。</li>
</ul>
<h3 id="3、DOS功能中的屏幕输出"><a href="#3、DOS功能中的屏幕输出" class="headerlink" title="3、DOS功能中的屏幕输出"></a>3、DOS功能中的屏幕输出</h3><p>屏幕输出是最常用的一种输出形式，DOS操作系统提供了几种实现屏幕输出的功能调用。INT 21H中的相关功能如下：</p>
<ul>
<li>02H——显示的字符</li>
<li>06H——控制台的输入/输出：当DL≠0FFH，表示显示字符</li>
<li>09H——在屏幕上显示一个字符串</li>
</ul>
<p>有关中断功能的详细描述和调用参数在此从略，需要查阅者可参阅附录3之字符功能调用类。</p>
<h3 id="4、BIOS中的屏幕操作功能"><a href="#4、BIOS中的屏幕操作功能" class="headerlink" title="4、BIOS中的屏幕操作功能"></a>4、BIOS中的屏幕操作功能</h3><p>BIOS系统提供了中断10H来实现各种屏幕处理功能。其具体的功能如下：</p>
<ul>
<li>00H——设置显示器模式</li>
<li>01H——设置光标形状</li>
<li>02H——设置光标位置</li>
<li>03H——读取光标信息</li>
<li>05H——设置显示页</li>
<li>06H、07H——初始化或滚屏(向上滚屏和向下滚屏)</li>
<li>08H——读光标处的字符及其属性</li>
<li>09H——在当前光标处按指定属性显示字符</li>
<li>0AH——在当前光标处显示字符</li>
<li>0CH——写图形象素</li>
<li>0DH——读图形象素</li>
<li>0EH——在Teletype模式下显示字符</li>
<li>0FH——读取显示器模式</li>
<li>10H——颜色</li>
<li>13H——在Teletype模式下显示字符串</li>
</ul>
<p>有关中断功能的详细描述和调用参数在此从略，需要查阅者可参阅附录3之显示服务。</p>
<h3 id="5、屏幕输出的举例"><a href="#5、屏幕输出的举例" class="headerlink" title="5、屏幕输出的举例"></a>5、屏幕输出的举例</h3><p><strong>例8.2 用直接写屏方式在屏幕第5行、第10列以黄色(0EH)显示字符串”Hello”。</strong></p>
<p>解：在文本显示方式下，每行显示80个字符，每个字符占2个字节，所以，显示一行需要160个字节。若在第m行、第n列位置显示字符，则该位置所对应存储单元的偏移量为：m×160 + n×2。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">.MODEL SMALL</span><br><span class="line"></span><br><span class="line">.DATA</span><br><span class="line"></span><br><span class="line">Yellow　EQU　0EH</span><br><span class="line"></span><br><span class="line">MSG1　DB　&quot;Welcome...&quot;</span><br><span class="line"></span><br><span class="line">Count　EQU　$-MSG1</span><br><span class="line"></span><br><span class="line">.CODE</span><br><span class="line"></span><br><span class="line">.STARTUP</span><br><span class="line"></span><br><span class="line">MOV AX, 0B800H</span><br><span class="line"></span><br><span class="line">MOV ES, AX ;彩色显示器的显示缓冲区段地址 </span><br><span class="line"></span><br><span class="line">MOV DI, 5</span><br><span class="line"></span><br><span class="line">IMUL DI, 160 ;5行所跳过的显示存储单元 </span><br><span class="line"></span><br><span class="line">MOV CX, 10</span><br><span class="line"></span><br><span class="line">SHL CX, 1 ;10列所跳过的显示存储单元 </span><br><span class="line"></span><br><span class="line">ADD DI, CX ;第5行、第10列之前所跳过的所有显示单元 </span><br><span class="line"></span><br><span class="line">MOV CX, Count</span><br><span class="line"></span><br><span class="line">LEA SI, MSG1 ;CX:字符个数，SI:显示字符首地址 </span><br><span class="line"></span><br><span class="line">MOV AH, Yellow ;设置显示属性，即显示颜色 </span><br><span class="line"></span><br><span class="line">.REPEAT</span><br><span class="line"></span><br><span class="line">LODSB ;取显示字符 </span><br><span class="line"></span><br><span class="line">STOSW ;向显示缓冲区设置显示字符和属性 </span><br><span class="line"></span><br><span class="line">.UNTILCXZ</span><br><span class="line"></span><br><span class="line">.EXIT　0</span><br><span class="line"></span><br><span class="line">END</span><br></pre></td></tr></table></figure>
<p><strong>例8.3 用“霓虹灯”的显示方式显示字符串”Hello”，按ESC键时结束程序的运行。</strong></p>
<p>解：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">.MODEL        SMALL, C</span><br><span class="line">.DATA</span><br><span class="line">　KBEsc　EQU　1BH </span><br><span class="line">　BUFF　DB　&quot;H&quot;, 15, &quot;e&quot;, 15, &quot;l&quot;, 15, &quot;l&quot;, 15, &quot;o&quot;, 15 </span><br><span class="line">.CODE</span><br><span class="line">       Clear  PROC      Near Uses AX BX CX DX   ;清屏幕，并保护所用寄存器</span><br><span class="line">              MOV       CL, 0</span><br><span class="line">              MOV       CH, 0</span><br><span class="line">              MOV       DL, 79</span><br><span class="line">              MOV       DH, 24      ;(0,0)-(24,79)是屏幕的左上角和右下角</span><br><span class="line">              MOV       BH, 7</span><br><span class="line">              MOV       AL, 0</span><br><span class="line">              MOV       AH, 6</span><br><span class="line">              INT       10H</span><br><span class="line">              RET</span><br><span class="line">       Clear  ENDP</span><br><span class="line">.STARTUP </span><br><span class="line">              CALL      Clear</span><br><span class="line">              MOV       AX, DS</span><br><span class="line">              MOV       ES, AX</span><br><span class="line">              MOV       SI, 9</span><br><span class="line">      again:</span><br><span class="line">              MOV       BUFF[SI], 15            ;把前一次的红色还原</span><br><span class="line">              ADD       SI, 2</span><br><span class="line">.IF           SI &gt; 9</span><br><span class="line">　　MOV　SI, 1</span><br><span class="line">.ENDIF</span><br><span class="line">              MOV       BUFF[SI], 12            ;把当前字符以红色显示</span><br><span class="line">              MOV       BH, 0</span><br><span class="line">              MOV       CX, 5</span><br><span class="line">              MOV       DH, 5</span><br><span class="line">              MOV       DL, 20      ;显示位置从(5, 20)开始</span><br><span class="line">              LEA       BP, BUFF</span><br><span class="line">              MOV       AL, 2</span><br><span class="line">              MOV       AH, 13H</span><br><span class="line">              INT       10H         ;调用中断10H之功能13H</span><br><span class="line">              MOV       AH, 1</span><br><span class="line">              INT       16H         ;检查是否有按键</span><br><span class="line">              JZ        again       ;若无字符可读，则继续循环</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              INT       16H</span><br><span class="line">              CMP       AL, KBEsc</span><br><span class="line">              JNZ       again       ;若按键不是Escape，则继续循环</span><br><span class="line">.EXIT　0 </span><br><span class="line">              END</span><br></pre></td></tr></table></figure>
<p><strong>例8.4 编写一个输入密码的程序，该程序的具体要求如下：</strong></p>
<p>1、每输入一个字符，显示字符”#”表示之；</p>
<p>2、密码最多只有10个字符，多余的按键被丢弃；</p>
<p>3、若输入的字符串为”HELLO”，则以蓝色显示”Welcome…”，否则，以闪烁、亮红色在显示”Invalid Password”。</p>
<p>解：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line">.MODEL        SMALL</span><br><span class="line">.DATA</span><br><span class="line">　CR　　　EQU　0DH</span><br><span class="line">　MSG1　DB　&quot;Welcome...&quot;</span><br><span class="line">　MSG2　DB　&quot;Invalid Password&quot;</span><br><span class="line">　PSW1　DB　&quot;HELLO&quot;</span><br><span class="line">　BUFF　DB　10 DUP(?) </span><br><span class="line">.CODE</span><br><span class="line"> .STARTUP </span><br><span class="line">              MOV       AX, DS</span><br><span class="line">              MOV       ES, AX</span><br><span class="line">              XOR       BX, BX</span><br><span class="line">      again:</span><br><span class="line">              MOV       AH, 0H</span><br><span class="line">              INT       16H         ;从键盘接受字符输入</span><br><span class="line">              CMP       AL, CR</span><br><span class="line">              JZ        next        ;若按“回车“键，则结束密码输入</span><br><span class="line">              CMP       BX, 10</span><br><span class="line">              JZ        again       ;若已接受了10个字符，则丢弃随后的字符</span><br><span class="line">.IF           AL&gt;=&apos;a&apos; &amp;&amp; AL&lt;=’z’</span><br><span class="line">　　SUB　 AL, 20H</span><br><span class="line">.ENDIF</span><br><span class="line">              MOV       BUFF[BX], AL</span><br><span class="line">              INC       BX          ;保存当前输入，并移动有关指针</span><br><span class="line">              MOV       DL, &apos;#&apos;</span><br><span class="line">              MOV       AH, 2</span><br><span class="line">              INT       21H         ;在屏幕上显示字符”#”</span><br><span class="line">              JMP       again</span><br><span class="line">       next:</span><br><span class="line">              CALL      Clear       ;清屏幕，见例8.2中的过程定义</span><br><span class="line">              CMP       BX, 5</span><br><span class="line">              JNZ       error       ;若输入的字符串长度不为5，则密码错误</span><br><span class="line">              LEA       SI, PSW1</span><br><span class="line">              LEA       DI, BUFF</span><br><span class="line">              MOV       CX, BX</span><br><span class="line">              CLD</span><br><span class="line">              REPE      CMPSB       ;比较字符串PSW1和BUFF</span><br><span class="line">.IF           ZERO?       ;若字符串的相应字符相同</span><br><span class="line">　　MOV　BP, OFFSET MSG1 ;显示字符串首地址 </span><br><span class="line">　　MOV　BL, 09H ;显示字符颜色：蓝色 </span><br><span class="line">　　MOV　CX, 0AH ;显示字符串长度：10 </span><br><span class="line">.ELSE</span><br><span class="line">　　MOV　BP, OFFSET MSG2 ;显示字符串首地址 </span><br><span class="line">　　MOV　BL, 8CH ;显示字符颜色：闪烁、亮红色 </span><br><span class="line">　　MOV　CX, 10H ;显示字符串长度：16 </span><br><span class="line">.ENDIF</span><br><span class="line">              MOV       AL, 0</span><br><span class="line">              MOV       BH, 0</span><br><span class="line">              MOV       DH, 5</span><br><span class="line">              MOV       DL, 20      ;在位置(5,20)的位置开始显示字符串</span><br><span class="line">              MOV       AH, 13H</span><br><span class="line">              INT       10H         ;使用中断10H之功能13H来显示字符串</span><br><span class="line">.EXIT　0 </span><br><span class="line">              END</span><br></pre></td></tr></table></figure>
<p><strong>例8.5 在256色320×200的图形显示模式下，从屏幕最左边向最右边，依次画竖线(从顶到底)，线的颜色从1依次加1。要求用中断调用的方法来画线。</strong></p>
<p>解：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">.MODEL        SMALL</span><br><span class="line">.DATA</span><br><span class="line">　 mode　DB　?　　　　　;保存当前显示模式</span><br><span class="line">.CODE</span><br><span class="line">       VLine  PROC      Near USES AX BX DX      ;画一条竖线，CX—竖线所在的列，AL—线的颜色</span><br><span class="line">              MOV       DX, 0</span><br><span class="line">              MOV       BH, 0</span><br><span class="line">              MOV       AH, 0CH</span><br><span class="line">       draw:</span><br><span class="line">       VLine  INT       10H</span><br><span class="line">              INC       DX</span><br><span class="line">              CMP       DX, 200</span><br><span class="line">              JL        draw</span><br><span class="line">              RET</span><br><span class="line">              ENDP</span><br><span class="line"> .STARTUP </span><br><span class="line">              MOV       AH, 0FH</span><br><span class="line">              INT       10H</span><br><span class="line">              MOV       mode, AL    ;保存当前显示模式，在程序结束前恢复之</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              MOV       AL, 13H</span><br><span class="line">              INT       10H         ;设置256色320×200的图形显示模式</span><br><span class="line">              MOV       CX, 0</span><br><span class="line">              MOV       AL, 01H     ;CX＝线所在列，AL＝线的颜色</span><br><span class="line">       draw:</span><br><span class="line">              CALL      VLine</span><br><span class="line">              INC       AL</span><br><span class="line">              INC       CX</span><br><span class="line">              CMP       CX, 320</span><br><span class="line">              JL        draw        ;从左到右画320条竖线</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              INT       16H         ;等待一个按键</span><br><span class="line">              MOV       AL, mode</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              INT       10H         ;恢复原来的屏幕显示模式</span><br><span class="line">.EXIT　0 </span><br><span class="line">              END</span><br></pre></td></tr></table></figure>
<p><strong>例8.6 在256色320×200的图形显示模式下，从屏幕顶到屏幕底依次画横线(从最左边到最右边)，线的颜色从1依次加1。要求用直接操作显示缓冲区的方法来画线。</strong></p>
<p>解：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">.MODEL        SMALL</span><br><span class="line">.DATA</span><br><span class="line">　 mode　DB　?　　　　　　　　　　;保存当前显示模式</span><br><span class="line">.CODE</span><br><span class="line">       HLine  PROC      Near USES CX DI         ;画一条横线，DI—横线所在行，AL—线的颜色</span><br><span class="line">              IMUL      DI, 320     ;跳过前面横所对应的字节，每行320个字节</span><br><span class="line">              MOV       CX, 320</span><br><span class="line">              REP       STOSB       ;重复设置AL的值</span><br><span class="line">              RET</span><br><span class="line">       HLine  ENDP</span><br><span class="line"> .STARTUP </span><br><span class="line">              MOV       AH, 0FH</span><br><span class="line">              INT       10H</span><br><span class="line">              MOV       mode, AL    ;保存当前显示模式，在程序结束前恢复之</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              MOV       AL, 13H</span><br><span class="line">              INT       10H         ;设置256色320×200的图形显示模式</span><br><span class="line">              MOV       AX, 0A000H</span><br><span class="line">              MOV       ES, AX      ;图形模式的段地址为0A000H</span><br><span class="line">              CLD</span><br><span class="line">              MOV       DI, 0</span><br><span class="line">              MOV       AL, 01H     ;CX＝线所在列，AL＝线的颜色</span><br><span class="line">       draw:</span><br><span class="line">              CALL      HLine</span><br><span class="line">              INC       AL</span><br><span class="line">              INC       DI</span><br><span class="line">              CMP       DI, 200</span><br><span class="line">              JL        draw        ;从上到下画200条横线</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              INT       16H         ;等待一个按键</span><br><span class="line">              MOV       AL, mode</span><br><span class="line">              MOV       AH, 0</span><br><span class="line">              INT       10H         ;恢复原来的屏幕显示模式</span><br><span class="line">.EXIT　0 </span><br><span class="line">              END</span><br></pre></td></tr></table></figure>
<h2 id="8-3-3-打印输出的中断功能"><a href="#8-3-3-打印输出的中断功能" class="headerlink" title="8.3.3 打印输出的中断功能"></a>8.3.3 打印输出的中断功能</h2><p>打印输出是一种硬拷贝输出，也是一种常用的输出形式。随着计算机应用领域的不断扩大，外围设备的重视程度也越来越高。目前，打印机的种类已日益丰富，有针式打印机、喷墨打印机和激光打印机等。从打印色彩来看，既有普通的黑色打印，也有彩色打印。总之，计算机打印输出的品质是越来越高。</p>
<h3 id="1、打印机状态字"><a href="#1、打印机状态字" class="headerlink" title="1、打印机状态字"></a>1、打印机状态字</h3><p>打印机状态字记录着打印机的当前工作情况(或状态)，它相当于CPU中的程序状态字和键盘状态字。打印机状态字的各位定义如图8.11所示。</p>
<p>若在某个程序中要包含打印功能，那么，程序员可通过打印状态字来了控制打印过程，并向使用者提供各种有用信息。比如：提示使用者“打印机无纸了”或打印机处于脱机状态(Off Line)等。</p>
<p><img src="http://www.iteedu.com/plang/asm/asmhbyychxshj/images/clip_image001_0107.gif" alt></p>
<center><strong>图8.11 打印机状态字节定义</strong></center>

<h3 id="2、打印控制命令"><a href="#2、打印控制命令" class="headerlink" title="2、打印控制命令"></a>2、打印控制命令</h3><p>在打印时，程序员往往要控制文本的输出格式，比如：换页、换行、字体或字号等。若要实现对打印格式的控制，就必须要知道控制打印机的控制字符和控制命令。一些常用的打印控制字符如表8.3所示。</p>
<p><strong>表8.3 常用的打印控制字符</strong></p>
<table>
<thead>
<tr>
<th>字符值</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>09H</td>
<td>水平制表符，跳到下一个制表位置</td>
</tr>
<tr>
<td>0AH</td>
<td>换行</td>
</tr>
<tr>
<td>0CH</td>
<td>换页</td>
</tr>
<tr>
<td>0DH</td>
<td>回车</td>
</tr>
</tbody>
</table>
<p>打印机还有其它的控制命令，如：ESC命令序列，该序列由字符ESC(其ASCII为1BH)和一些数值组成。表8.4列举了LQ-1600K打印机的几个控制命令。对于其它各类打印机的控制命令，要参阅其使用手册。</p>
<p><strong>表8.4 LQ-1600K打印机的几个控制命令</strong></p>
<table>
<thead>
<tr>
<th>控制命令</th>
<th>命令的数值</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>ESC @</td>
<td>1BH 40H</td>
<td>初始化打印机</td>
</tr>
<tr>
<td>ESC 4/ESC 5</td>
<td>1BH 34H／1BH 35H</td>
<td>设定／取消斜体打印</td>
</tr>
<tr>
<td>ESC S 0/ESC S 1</td>
<td>1BH 53 0／1BH 53 1</td>
<td>设定上／下角标打印</td>
</tr>
<tr>
<td>ESC T</td>
<td>1BH 54H</td>
<td>取消上／下角标打印</td>
</tr>
<tr>
<td>ESC l n</td>
<td>1BH 6CH n</td>
<td>设定左边界，n为当前字符的宽度</td>
</tr>
</tbody>
</table>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/limh/tags/教程/" rel="tag"># 教程</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/limh/2015/04/01/asm35/" rel="next" title="8.2 中断">
                <i class="fa fa-chevron-left"></i> 8.2 中断
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/limh/2015/04/01/asm37/" rel="prev" title="9.1 宏的定义和引用">
                9.1 宏的定义和引用 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="SOHUCS"></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/limh/images/avatar.jpg" alt="土逗牛肉">
            
              <p class="site-author-name" itemprop="name">土逗牛肉</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/limh/archives/">
              
                  <span class="site-state-item-count">255</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/limh/categories/index.html">
                  <span class="site-state-item-count">8</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/limh/tags/index.html">
                  <span class="site-state-item-count">7</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/limhGeek" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="mailto:1591054297@qq.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://www.jianshu.com/u/f73b243e7cc9" target="_blank" title="简书">
                      
                        <i class="fa fa-fw fa-user-circle-o"></i>简书</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#8-3-1-键盘输入的中断功能"><span class="nav-number">1.</span> <span class="nav-text">8.3.1 键盘输入的中断功能</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1、键盘缓冲区"><span class="nav-number">1.1.</span> <span class="nav-text">1、键盘缓冲区</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2、键盘状态字"><span class="nav-number">1.2.</span> <span class="nav-text">2、键盘状态字</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3、键盘中断的处理过程"><span class="nav-number">1.3.</span> <span class="nav-text">3、键盘中断的处理过程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4、DOS功能中的键盘输入"><span class="nav-number">1.4.</span> <span class="nav-text">4、DOS功能中的键盘输入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5、BIOS中的键盘输入"><span class="nav-number">1.5.</span> <span class="nav-text">5、BIOS中的键盘输入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6、直接操作端口的键盘输入"><span class="nav-number">1.6.</span> <span class="nav-text">6、直接操作端口的键盘输入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7、键盘输入的举例"><span class="nav-number">1.7.</span> <span class="nav-text">7、键盘输入的举例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#8-3-2-屏幕显示的中断功能"><span class="nav-number">2.</span> <span class="nav-text">8.3.2 屏幕显示的中断功能</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1、显示模式"><span class="nav-number">2.1.</span> <span class="nav-text">1、显示模式</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-、文本显示方式"><span class="nav-number">2.1.1.</span> <span class="nav-text">1)、文本显示方式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-、图形显示方式"><span class="nav-number">2.1.2.</span> <span class="nav-text">2)、图形显示方式</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#1-、4色320×200图形显示模式"><span class="nav-number">2.1.2.1.</span> <span class="nav-text">(1)、4色320×200图形显示模式</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-、16色640×480图形显示模式"><span class="nav-number">2.1.2.2.</span> <span class="nav-text">(2)、16色640×480图形显示模式</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#3-、256色320×200图形显示模式"><span class="nav-number">2.1.2.3.</span> <span class="nav-text">(3)、256色320×200图形显示模式</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2、显示缓冲区"><span class="nav-number">2.2.</span> <span class="nav-text">2、显示缓冲区</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3、DOS功能中的屏幕输出"><span class="nav-number">2.3.</span> <span class="nav-text">3、DOS功能中的屏幕输出</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4、BIOS中的屏幕操作功能"><span class="nav-number">2.4.</span> <span class="nav-text">4、BIOS中的屏幕操作功能</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5、屏幕输出的举例"><span class="nav-number">2.5.</span> <span class="nav-text">5、屏幕输出的举例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#8-3-3-打印输出的中断功能"><span class="nav-number">3.</span> <span class="nav-text">8.3.3 打印输出的中断功能</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1、打印机状态字"><span class="nav-number">3.1.</span> <span class="nav-text">1、打印机状态字</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2、打印控制命令"><span class="nav-number">3.2.</span> <span class="nav-text">2、打印控制命令</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">土逗牛肉</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
	var str = GetUrlParam('height');
    if (str === '0'){
		document.getElementById('header').style.display = 'none';
		document.getElementById('comments').style.display = 'none';
		document.getElementById('footer').style.display = 'none';
		document.getElementsByClassName('post-footer').item(0).style.display = 'none'
	}
	
    function GetUrlParam(paraName) {
        var url = document.location.toString();
        var arrObj = url.split("?");

        if (arrObj.length > 1) {
            var arrPara = arrObj[1].split("&");
            var arr;

            for (var i = 0; i < arrPara.length; i++) {
                 arr = arrPara[i].split("=");

                if (arr != null && arr[0] === paraName) {
                    return arr[1];
                }
            }
            return "";
        } else {
            return "";
        }
    }
</script>









  












  
  
    <script type="text/javascript" src="/limh/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/limh/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/limh/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/limh/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/limh/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/limh/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/limh/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/limh/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/limh/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
